<script lang="ts" setup>
import { ref, computed, watch } from "vue";
import { onLoad, onShow } from "@dcloudio/uni-app"
import { getAreaWeather, getArea24HoursWeather, getAreaFutureWeather, getAreaCode } from "@/api/index";
import { AreaWeatherListType } from "@/type/index.ts";
import dayIcon from "@/common/dayIcon.js";
import nightIcon from "@/common/nightIcon.js";
import { getDateTime, getWeekSimplify } from "@/utils/index.js";
import UniWeather from "@/components/uni-weather/index.vue";

let WXSDK = null;
let WXJSSDK = null;
const TX_MAP_KEY = "427BZ-W2IWV-ZNXPZ-U4D7M-2ACVS-XPBEB";
let longitude = 0;
let latitude = 0;

/**
 * 小程序--腾讯地图SDK
 */
// #ifdef MP-WEIXIN
WXSDK = require("../../static/js/qqmap-wx-jssdk.js");
WXJSSDK = new WXSDK({
  key: TX_MAP_KEY
});
// #endif

// 读取天气数据
const areaWeatherListStorage = uni.getStorageSync("areaWeatherList");
const areaWeatherList = ref<AreaWeatherListType[]>([]);
if (areaWeatherListStorage) {
  areaWeatherList.value = JSON.parse(areaWeatherListStorage);
}

// 数据索引
const areaIndex = ref(uni.getStorageSync("areaIndex") || 0);
// 内容展示状态
const state = ref(false);
// 未来天气天数
const futureWeatherDay = ref(7);
// 当前区域天气
const currentAreaWeather = computed(() => {
  return areaWeatherList.value[areaIndex.value] || null;
});

// 当前天天气
const currentDayWeather = computed(() => {
  if (!currentAreaWeather.value) {
    return null;
  }
  return currentAreaWeather.value.areaWeather.f1;
});
// 当前天天气预警
const currentAlarmList = computed(() => {
  if (!currentAreaWeather.value) {
    return null;
  }
  return currentAreaWeather.value.areaWeather.alarmList;
});
// 现在天气
const nowWeather = computed(() => {
  if (!currentAreaWeather.value) {
    return null;
  }
  return currentAreaWeather.value.areaWeather.now;
});
// 当前24小时天气
const current24HoursWeather = computed(() => {
  if (!currentAreaWeather.value) {
    return null;
  }
  return currentAreaWeather.value.area24HoursWeather;
});
// 当前24小时天气
const current24HoursList = computed(() => {
  if (!currentAreaWeather.value || !current24HoursWeather.value.hourList) {
    return [];
  }
  return current24HoursWeather.value.hourList.map((item, i) => {
    const hours = item.time.substring(8, 10);
    const minutes = item.time.substring(10, 12);
    if (i === 0) {
      item.timeName = "现在";
    } else {
      item.timeName = hours + ":" + minutes;
    }
    if (Number(hours) > 20 || Number(hours) < 6) {
      item.icon = nightIcon[item.weather_code];
    } else {
      item.icon = dayIcon[item.weather_code];
    }
    return item;
  });
});
// 未来15天天气
const futureWeather = computed(() => {
  if (!currentAreaWeather.value || !currentAreaWeather.value.areaFutureWeather || !currentAreaWeather.value.areaFutureWeather.dayList) {
    return [];
  }
  return currentAreaWeather.value.areaFutureWeather.dayList.map((item, i) => {
    const year = getDateTime("", "yyyy");
    const month = item.daytime.substring(4, 6);
    const day = item.daytime.substring(6, 8);
    item.time = Number(month) + "月" + day + "日";
    if (i === 0) {
      item.week = "今天";
    } else if (i === 1) {
      item.week = "明天";
    } else {
      item.week = getWeekSimplify(year + "-" + month + "-" + day);
    }
    return item;
  });
});
watch(areaIndex, () => {
  uni.setStorageSync("areaIndex", areaIndex.value);
});

// 初始化
onLoad(() => {
  // 没有天气数据
  if (!areaWeatherList.value.length) {
    getLocationFn();
  } else {
    // 地名--查询天气
    getAreaWeatherFn();
  }
});
// 当前页面显示时
onShow(()=>{
  // 读取存储选择的城市
  const selectCity = uni.getStorageSync("selectCity");
  if (selectCity) {
    // 删除
    uni.removeStorageSync("selectCity");
    uni.showLoading({
      title: "加载中...",
      mask: true
    });
    // 设置状态
    state.value = false;
    // 读取新数据
    const areaWeatherListStorage = uni.getStorageSync("areaWeatherList");
    if (areaWeatherListStorage) {
      areaWeatherList.value = JSON.parse(areaWeatherListStorage);
    }
    // 是否包含
    const exist = areaWeatherList.value.findIndex(item => item.areaName === selectCity);
    if (exist > -1) {
      // 设置索引
      areaIndex.value = exist;
    } else {
      // 设置数据
      areaWeatherList.value.push({
        location: false,
        areaName: selectCity,
        areaCode: "",
        areaWeather: {},
        area24HoursWeather: {},
        areaFutureWeather: {}
      });
      // 设置索引
      areaIndex.value = areaWeatherList.value.length - 1;
    }
    // 地名--查询对应的地名code
    getAreaCodeFn();
  }
});

/**
 * 获取--经纬度
 */
const getLocationFn = () => {
  uni.showLoading({
    title: "加载中...",
    mask: true
  });
  // 定位
  uni.getLocation({
    type: "wgs84",
    success: res => {
      if (res.longitude) {
        // 设置经纬度
        longitude = res.longitude;
        latitude = res.latitude;
        // 获取--经纬度解析城市信息
        getCityInfoFn();
      } else {
        failInfoFn();
      }
    },
    fail: () => {
      failInfoFn();
    }
  });
};

/**
 * 获取--经纬度解析城市信息
 */
const getCityInfoFn = () => {
  // #ifdef APP
  getAppCityInfoFn();
  // #endif

  // #ifdef H5
  getH5CityInfoFn();
  // #endif

  // #ifdef MP-WEIXIN
  getWXCityInfoFn();
  // #endif
};

/**
 * 获取-APP经纬度解析城市信息
 */
const getAppCityInfoFn = () => {
  // 设置页面路径
  const path = `/hybrid/html/map.html?handle=getCityInfo&longitude=${longitude}&latitude=${latitude}`;
  // 设置webview
  const wv = plus.webview.create(path, "getCityInfo", {
    width: "0px",
    height: "0px"
  });
  // 显示webview
  wv.show();
  // 监听webview
  wv.overrideUrlLoading({ effect: "instant" }, res => {
    if (res && res.url && res.url.indexOf("myapp://getCityInfo") > -1) {
      // 关闭webview
      plus.webview.close(wv);
      // 获取城市
      let areaName = decodeURIComponent(res.url).split("areaName=")[1];
      if (areaName) {
        // 设置数据
        areaWeatherList.value.push({
          location: true,
          areaName: areaName,
          areaCode: "",
          areaWeather: {},
          area24HoursWeather: {},
          areaFutureWeather: {}
        });
        // 设置索引
        areaIndex.value = 0;
        // 地名--查询对应的地名code
        getAreaCodeFn();
      } else {
        failInfoFn();
      }
    } else {
      failInfoFn();
    }
  });
};

/**
 * 获取-H5经纬度解析城市信息
 */
const getH5CityInfoFn = () => {
  let geocoder = null;
  // 初始化‌地理编码
  AMap.plugin("AMap.Geocoder", () => {
    geocoder = new AMap.Geocoder({
      radius: 1000,
      extensions: "all"
    });
  });
  // 根据经纬度进行逆地理编码查询
  geocoder.getAddress([longitude, latitude], (status, res) => {
    if (status === "complete" && res.info === "OK") {
      if (res.regeocode && res.regeocode.formattedAddress) {
        // 获取城市
        const areaName = res.regeocode.addressComponent.district;
        // 设置数据
        areaWeatherList.value.push({
          location: true,
          areaName: areaName,
          areaCode: "",
          areaWeather: {},
          area24HoursWeather: {},
          areaFutureWeather: {}
        });
        // 设置索引
        areaIndex.value = 0;
        // 地名--查询对应的地名code
        getAreaCodeFn();
      } else {
        failInfoFn();
      }
    } else {
      failInfoFn();
    }
  });
};

/**
 * 获取-小程序经纬度解析城市信息
 */
const getWXCityInfoFn = () => {
  // 初始化‌地理编码
  WXJSSDK.reverseGeocoder({
    sig: TX_MAP_KEY,
    location: {
      latitude: latitude,
      longitude: longitude
    },
    success: res => {
      if (res.result && res.result.address_component) {
        // 获取城市
        const areaName = res.result.address_component.district;
        // 设置数据
        areaWeatherList.value.push({
          location: true,
          areaName: areaName,
          areaCode: "",
          areaWeather: {},
          area24HoursWeather: {},
          areaFutureWeather: {}
        });
        // 设置索引
        areaIndex.value = 0;
        // 地名--查询对应的地名code
        getAreaCodeFn();
      } else {
        failInfoFn();
      }
    },
    fail: () => {
      failInfoFn();
    }
  });
};

/**
 * 地名--查询对应的地名code
 */
const getAreaCodeFn = () => {
  const data = {
    area: areaWeatherList.value[areaIndex.value].areaName
  };
  getAreaCode(data).then(res => {
    if (res.showapi_res_body.list && res.showapi_res_body.list.length) {
      areaWeatherList.value[areaIndex.value].areaCode = res.showapi_res_body.list[0].areaCode;
      // 地名--查询天气
      getAreaWeatherFn();
    } else {
      getWeatherInfoFailFn(res);
    }
  }).catch(err => {
    getWeatherInfoFailFn(err);
  });
};

/**
 * 地名--查询天气
 */
const getAreaWeatherFn = () => {
  const data = {
    areaCode: currentAreaWeather.value.areaCode,
    area: currentAreaWeather.value.areaName,
    needMoreDay: 0,
    needIndex: 1,
    need3HourForcast: 1,
    needAlarm: 1,
    needHourData: 0
  };
  getAreaWeather(data).then(res => {
    if (!res.showapi_res_error) {
      areaWeatherList.value[areaIndex.value].areaWeather = res.showapi_res_body;
      // 地名--查询24小时预报
      getArea24HoursWeatherFn();
    } else {
      getWeatherInfoFailFn(res);
    }
  }).catch(err => {
    getWeatherInfoFailFn(err);
  });
};

/**
 * 地名--查询24小时预报
 */
const getArea24HoursWeatherFn = () => {
  const data = {
    areaCode: currentAreaWeather.value.areaCode,
    area: currentAreaWeather.value.areaName
  };
  getArea24HoursWeather(data).then(res => {
    if (!res.showapi_res_error) {
      areaWeatherList.value[areaIndex.value].area24HoursWeather = res.showapi_res_body;
      // 地名--查未来15天预报
      getAreaFutureWeatherFn();
    } else {
      getWeatherInfoFailFn(res);
    }
  }).catch(err => {
    getWeatherInfoFailFn(err);
  });
};

/**
 * 地名--查未来15天预报
 */
const getAreaFutureWeatherFn = () => {
  const data = {
    areaCode: currentAreaWeather.value.areaCode,
    area: currentAreaWeather.value.areaName
  };
  getAreaFutureWeather(data).then(res => {
    areaWeatherList.value[areaIndex.value].areaFutureWeather = res.showapi_res_body;
    uni.hideLoading();
    // 存储数据
    uni.setStorageSync("areaWeatherList", JSON.stringify(areaWeatherList.value));
    // 设置内容展示状态
    state.value = true;
  }).catch(err => {
    getWeatherInfoFailFn(err);
  });
};

/**
 * 跳转城市管理
 */
const toCityManagement = () => {
  uni.navigateTo({
  	url: "/pages/cityManagement/index"
  })
};

/**
 * 定位与解析失败处理
 */
const failInfoFn = () => {
  uni.hideLoading();
	uni.showModal({
		title: "提示",
		content: "定位失败，需要手动选择城市",
		showCancel: false,
		success: () => {
			uni.navigateTo({
				url: "/pages/cityChoose/index"
			});
		}
	});
};

/**
 * 天气接口失败处理
 */
const getWeatherInfoFailFn = err => {
  uni.hideLoading();
  uni.showModal({
    title: "提示",
    content: err.showapi_res_error || "加载失败",
    showCancel: false,
    success: () => {
      uni.navigateTo({
        url: "/pages/cityChoose/index"
      });
    }
  });
};

/**
 * 查看未来15日天气预报
 */
const changeFutureWeatherDay = () => {
  futureWeatherDay.value === 7 ? futureWeatherDay.value = 15 : futureWeatherDay.value = 7;
};
</script>

<template>
  <view class="page-index flex-column h-full overflow-auto">
    <UniWeather v-if="state" :weather-code="nowWeather.weather_code" :temperature-time="nowWeather.temperature_time" type="NightSky" />
    <view v-if="state" class="flex flex-center z-index-10">
      <view class="flex flex-center">
        <text class="f-s-40 font-weight color-white">{{ currentAreaWeather.areaName }}</text>
        <text v-if="currentAreaWeather.location" class="fa fa-map-marker color-white m-l-10"></text>
      </view>
      <view class="flex1"></view>
      <view @click="toCityManagement" class="flex flex-center">
        <text class="fa fa-map-o f-s-40 color-white"></text>
      </view>
    </view>
    <view v-if="state" class="flex1 z-index-10">
      <view class="weather-info">
        <view class="h-300 flex-column flex-center">
          <view class="weather-info-num color-white font-weight">
            {{ nowWeather.temperature }}°
          </view>
          <view class="f-s-40 color-white m-t-40">
            <text>{{ nowWeather.weather }}</text>
            <text class="m-l-20">{{ currentDayWeather.night_air_temperature }}°</text>
            <text>/</text>
            <text>{{ currentDayWeather.day_air_temperature }}°</text>
            <text class="m-l-20">空气{{ nowWeather.aqiDetail.quality }}</text>
            <text class="m-l-20">{{ nowWeather.aqiDetail.aqi }}</text>
          </view>
        </view>
      </view>
      <view class="weather-desc">
        <swiper :circular="true" :indicator-dots="true" :autoplay="true" :interval="3000" :duration="500">
          <swiper-item v-for="(item, i) in currentAlarmList" :key="i">
            <view class="flex-column w-full h-full overflow-hidden">
              <view class="flex flex-align color-white">
                <text class="fa fa-warning f-s-40"></text>
                <text class="f-s-40 m-l-20">{{ item.signalType }}{{ item.signalLevel }}预警</text>
              </view>
              <div class="m-t-20 h-80 f-s-30 color-white ellipsis-2 l-h-40">
                {{ item.issueContent }}
              </div>
            </view>
          </swiper-item>
          <swiper-item>
            <view class="flex-column w-full h-full overflow-hidden">
              <view class="flex flex-align color-white">
                <text class="f-s-40">穿衣-{{ currentDayWeather.index.clothes.title }}</text>
              </view>
              <div class="m-t-20 h-80 f-s-30 color-white ellipsis-2 l-h-40">
                {{ currentDayWeather.index.clothes.desc }}
              </div>
            </view>
          </swiper-item>
          <swiper-item>
            <view class="flex-column w-full h-full overflow-hidden">
              <view class="flex flex-align color-white">
                <text class="f-s-40">旅游-{{ currentDayWeather.index.travel.title }}</text>
              </view>
              <div class="m-t-20 h-80 f-s-30 color-white ellipsis-2 l-h-40">
                {{ currentDayWeather.index.travel.desc }}
              </div>
            </view>
          </swiper-item>
          <swiper-item>
            <view class="flex-column w-full h-full overflow-hidden">
              <view class="flex flex-align color-white">
                <text class="f-s-40">中暑-{{ currentDayWeather.index.zs.title }}</text>
              </view>
              <div class="m-t-20 h-80 f-s-30 color-white ellipsis-2 l-h-40">
                {{ currentDayWeather.index.zs.desc }}
              </div>
            </view>
          </swiper-item>
        </swiper>
      </view>
      <view class="weather-recently flex">
        <view v-for="(item, i) in current24HoursList" :key="i" class="flex-column flex-center min-w-140">
          <text class="f-s-32 color-white">{{ item.timeName }}</text>
          <image class="w-60 h-60 m-t-10" :src="item.icon"></image>
          <text class="f-s-38 color-white font-weight m-t-10">{{ item.temperature }}°</text>
        </view>
      </view>
      <view class="weather-future w-full">
        <view v-for="(item, i) in futureWeather.slice(0, futureWeatherDay)" :key="i" class="flex flex-center h-90 w-full">
          <text class="f-s-32 color-white font-weight l-s-4">{{ item.time }}</text>
          <text class="f-s-32 color-white font-weight m-l-10">{{ item.week }}</text>
          <view class="flex1 flex flex-center">
            <image class="w-60 h-60" :src="item.day_weather_pic"></image>
          </view>
          <text class="f-s-32 color-white font-weight">{{ item.night_air_temperature }}°</text>
          <text class="f-s-32 color-info m-l-10 m-r-10">/</text>
          <text class="f-s-32 color-white font-weight">{{ item.day_air_temperature }}°</text>
        </view>
        <view @click="changeFutureWeatherDay" class="weather-future-more actives-6 m-t-20">
          {{ futureWeatherDay > 7 ? "收起" : "未来15日天气预报" }}
        </view>
      </view>
    </view>
  </view>
</template>
